package com.blumov.fastbox.webservices.parsers;

import java.util.ArrayList;
import java.util.List;

import com.blumov.fastbox.compra.BandejaDTO;
import com.blumov.fastbox.compra.ItemPedidoDTO;
import com.blumov.fastbox.compra.PedidoDTO;

/**
 * Parser para convertir los pedidos hacia y desde el webservice 
 * 
 * @author Bruno Masci
 *
 */
public class PedidoParser implements Parser<List<BandejaDTO>> {
	
	/**
	 * Simbolo utilizado para separar el contenido de cada bandeja
	 */
	private final static char SEPARADOR_BANDEJAS = '#';
	
	/**
	 * Simbolo utilizado para  separar cada producto
	 */
	private final static char SEPARADOR_PRODUCTOS = '&';
	

	private StringBuffer productoActual;
	private BandejaDTO bandejaActual;
	private List<BandejaDTO> pedidoDTO;
	
	
	/**
	 * Default constructor
	 */
	public PedidoParser() {
		this.productoActual = new StringBuffer();
		this.bandejaActual = new BandejaDTO();
		this.pedidoDTO = new ArrayList<BandejaDTO>();
	}
	
	/**
	 * Convierte un pedido en un conjunto de {@link BandejaDTO}
	 */
	public List<BandejaDTO> parse(String pedido) {	
		/*
		 * La idea es ir armando cada id de producto como String para despues transformarlo en un ItemPedidoDTO.
		 * El fin de un producto lo indica la aparicion de un separador de bandejas, de un separador de productos 
		 * o el fin del pedido mismo.
		 */
		final int sizePedido = pedido.length();
		
		for (int i = 0; i < sizePedido; i++) {
			final char caracterActual = pedido.charAt(i);
			switch (caracterActual) {
				case SEPARADOR_PRODUCTOS:
					this.agregarProductoABandeja();
					break;
				case SEPARADOR_BANDEJAS:
					this.agregarBandejaAPedido();
					break;
				default:	// es un producto
					productoActual.append(caracterActual);
					break;
			}
		}
		
		this.agregarBandejaAPedido();
		
		return this.pedidoDTO;
	}

	/**
	 * Convierte un conjunto de paquetes de {@link BandejaDTO} en un string
	 */
	public String parse(List<BandejaDTO> pedidoDTO) {
		StringBuffer pedido = new StringBuffer();
		
		for (BandejaDTO bandejaDTO : pedidoDTO) {
			for (ItemPedidoDTO itemPedidoDTO : bandejaDTO.getItems()) {
				pedido.append(itemPedidoDTO.getCodigoProducto());
				pedido.append(SEPARADOR_PRODUCTOS);
			}
			
			pedido.deleteCharAt(pedido.length() - 1);
			pedido.append(SEPARADOR_BANDEJAS);
		}
		
		pedido.deleteCharAt(pedido.length() - 1);
		
		return pedido.toString();
	}
	
	public String parsePedidoACocinar(PedidoDTO pedidoDTO) {

		StringBuffer pedidoStr = new StringBuffer();
		
		pedidoStr.append(pedidoDTO.getNumero());
		pedidoStr.append("*");
		
		for (BandejaDTO bandejaDTO : pedidoDTO.getBandejas()) {
			for (ItemPedidoDTO itemDTO : bandejaDTO.getItems()) {
				pedidoStr.append(itemDTO.getCodigoProducto());
				pedidoStr.append("&");
			}
		}
		
		pedidoStr.deleteCharAt(pedidoStr.length() - 1);
		
		return pedidoStr.toString();
	}
	
	/**
	 * NOTA: 'Pendientes' en el contexto de la interfaz publica 
	 */
	public String parsePedidosListosOPendientes(List<PedidoDTO> pedidosListosOPendientes) {
		
		StringBuffer pedidosStr = new StringBuffer();
		
		for (PedidoDTO pedido : pedidosListosOPendientes) {
			pedidosStr.append(pedido.getNumero());
			pedidosStr.append("|");
			pedidosStr.append("1");
			pedidosStr.append("#");
			pedidosStr.append(pedido.getHoraCreacion());
			pedidosStr.append("%");
		}
		
		// Borrar el ultimo '%'
		if (pedidosStr.length() > 0) {
			pedidosStr.deleteCharAt(pedidosStr.length() - 1);
		}
		
		return pedidosStr.toString();
	}
	
	public String parsePedidoDispatcher(PedidoDTO pedidoDTO) {
		
		StringBuffer pedidoStr = new StringBuffer();
		
		pedidoStr.append(pedidoDTO.getNumero());
		pedidoStr.append("*");
		pedidoStr.append(pedidoDTO.getPrecio());
		pedidoStr.append("+");
		
		for (BandejaDTO bandejaDTO : pedidoDTO.getBandejas()) {
			for (ItemPedidoDTO itemDTO : bandejaDTO.getItems()) {
				pedidoStr.append(itemDTO.getCodigoProducto());
				pedidoStr.append("&");
			}
			
			pedidoStr.deleteCharAt(pedidoStr.length() - 1);
			pedidoStr.append("#");
		}
		
		pedidoStr.deleteCharAt(pedidoStr.length() - 1);
		return pedidoStr.toString();
	}
	
	private void agregarBandejaAPedido() {
		this.agregarProductoABandeja();
		this.pedidoDTO.add(this.bandejaActual);
		this.vaciarBandejaActual();
	}
	
	private void agregarProductoABandeja() {
		String codigoProducto = this.productoActual.toString();
		ItemPedidoDTO itemPedidoDTO = new ItemPedidoDTO(codigoProducto);
		this.vaciarItemActual();
		this.bandejaActual.addItem(itemPedidoDTO);
	}
	
	/**
	 * Vacia el producto actual para comenzar a utilizarlo con uno nuevo
	 */
	private void vaciarItemActual() {
		this.productoActual = new StringBuffer();
	}
	
	/**
	 * Vacia la bandeja actual para comenzar a utilizarla de nuevo
	 */
	private void vaciarBandejaActual() {
		this.bandejaActual = new BandejaDTO();
	}
}
